/*
 * MIT License
 *
 * Copyright (c) 2023 芊芊墨客
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */

package com.zhangmeng.tools.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import com.sun.javafx.iio.ImageStorage;
import com.zhangmeng.tools.utils.AlertUtils;
import com.zhangmeng.tools.utils.ImagePath;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ColorPicker;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.w3c.dom.ls.LSInput;

import java.awt.*;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author : 芊芊墨客
 * @version : 1.0
 * @date : 2023-02-23 11:39
 */
@Slf4j
public class QrCodeController {

    @FXML
    private TextField width;

    @FXML
    private TextField height;

    @FXML
    private TextField margin;

    @FXML
    private ColorPicker qr_code_fore_image;

    @FXML
    private ColorPicker qr_code_back_image;

    @FXML
    private TextField content;

    @FXML
    private AnchorPane image_root;

    @FXML
    private Button file_choose_button;

    @FXML
    private TextField base_path;

    @FXML
    private ComboBox<ErrorCorrectionLevel> comboBox;

    @FXML
    private Button logo_button;

    @FXML
    private TextField logo_path;

    @FXML
    private TextArea res_content;

    private ObservableList<ErrorCorrectionLevel> list = FXCollections.observableArrayList();
    private SimpleObjectProperty<File> logo = new SimpleObjectProperty<>();
    private SimpleObjectProperty<File> targetFile_cache = new SimpleObjectProperty<>();

    @FXML
    public void get_text(){
        if (targetFile_cache.getValue() == null){
            AlertUtils.alert_warning("没有可识别的二维码!");
            return;
        }
        File value = targetFile_cache.getValue();
        String decode = QrCodeUtil.decode(value);
        res_content.setText(decode);
    }

    @FXML
    public void file_choose_dir() {
        Stage stage = new Stage();
        DirectoryChooser dc = new DirectoryChooser();
        dc.setTitle("文件夹选择器");
        File file = dc.showDialog(stage);
        if (file != null) {
            log.info(file.getAbsolutePath());
            base_path.setText(file.getPath());
        }
    }

    @FXML
    public void file_choose_logo() {
        Stage stage = new Stage();
        FileChooser fc = new FileChooser();
        fc.setTitle("单选文件");
        fc.getExtensionFilters().addAll(
                new FileChooser.ExtensionFilter("图片类型", "*.jpg", "*.png")
        );

        File file = fc.showOpenDialog(stage);
        if (file == null) {
            return;
        }
        logo_path.setText(file.getAbsolutePath());
        logo.setValue(file);
    }

    @FXML
    public void qr_code_preview() {
        qr_code_gen();
    }

    private void qr_code_gen() {
        if (width.getText().length() == 0) {
            AlertUtils.alert_warning("请输入图片宽度!");
            return;
        }

        if (height.getText().length() == 0) {
            AlertUtils.alert_warning("请输入图片高度!");
            return;
        }

        if (base_path.getText().length() == 0) {
            AlertUtils.alert_warning("请选择文件夹!");
            return;
        }

        if (content.getText().length() == 0) {
            AlertUtils.alert_warning("请输入内容!");
            return;
        }

        boolean flag_margin = false;
        if (margin.getText().length() != 0) {
            try {
                Integer.parseInt(margin.getText());
            } catch (NumberFormatException e) {
               AlertUtils.alert_warning("二维码和背景之间的边距为数字!");
               return;
            }
            flag_margin = true;
        }

        javafx.scene.paint.Color fore_color = qr_code_fore_image.getValue();
        javafx.scene.paint.Color back_color = qr_code_back_image.getValue();

        QrConfig config = new QrConfig(Integer.parseInt(width.getText()), Integer.parseInt(height.getText()));
        // 设置边距，既二维码和背景之间的边距
        if (flag_margin) {
            config.setMargin(Integer.parseInt(margin.getText()));
        }
        // 设置前景色，既二维码颜色（青色）
        double red = fore_color.getRed();
        double green = fore_color.getGreen();
        double blue = fore_color.getBlue();
        Color color1 = new Color((float) red, (float) green, (float) blue);

        // 设置背景色（灰色）
        double red1 = back_color.getRed();
        double green1 = back_color.getGreen();
        double blue1 = back_color.getBlue();
        Color color2 = new Color((float) red1, (float) green1, (float) blue1);

        config.setForeColor(color1);
        log.info("fore_color:---red:{},green:{},blue:{}", color1.getRed(), color1.getGreen(), color1.getBlue());

        config.setBackColor(color2);
        log.info("fore_color:---red:{},green:{},blue:{}", color2.getRed(), color2.getGreen(), color2.getBlue());

        ErrorCorrectionLevel errorCorrectionLevel = comboBox.getSelectionModel().getSelectedItem();
        if (logo.getValue() != null){
            config.setImg(logo.getValue());
        }
        config.setErrorCorrection(errorCorrectionLevel);
        File targetFile = FileUtil.file(base_path.getText() + File.separator + file_name());
        QrCodeUtil.generate(content.getText(), config, targetFile);
        ImageView imageView = new ImageView(new Image(targetFile.getPath()));
        image_root.getChildren().clear();
        image_root.getChildren().add(imageView);
        targetFile_cache.setValue(targetFile);
    }

    public static String file_name() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        return simpleDateFormat.format(new Date()) + ".jpg";
    }

    @FXML
    public void initialize() {
        ErrorCorrectionLevel[] values = ErrorCorrectionLevel.values();
        list.addAll(values);
        comboBox.setItems(list);
        comboBox.getSelectionModel().select(0);
        comboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                log.info("纠错级别!{}",newValue.getBits());
            }
        });

        Color black = Color.white;
        qr_code_back_image.setValue(javafx.scene.paint.Color.rgb(black.getRed(), black.getGreen(), black.getBlue()));

        Color fore = Color.black;
        qr_code_fore_image.setValue(javafx.scene.paint.Color.rgb(fore.getRed(), fore.getGreen(), fore.getBlue()));

        file_choose_button.setText(null);
        ImageView iv = new ImageView(new Image(ImagePath.path(ImagePath.ImagePathType.IMAGE_FILE)));
        iv.setPreserveRatio(true);
        iv.setFitWidth(18);
        file_choose_button.setGraphic(iv);

        logo_button.setText(null);
        ImageView iv2 = new ImageView(new Image(ImagePath.path(ImagePath.ImagePathType.IMAGE_FILE)));
        iv2.setPreserveRatio(true);
        iv2.setFitWidth(18);
        logo_button.setGraphic(iv2);

        if (width.getText().length() == 0) {
            width.setText("300");
        }

        if (height.getText().length() == 0) {
            height.setText("300");
        }

        width.textProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                log.info("width exchange : {}", newValue);
            }
        });

        height.textProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                log.info("height exchange : {}", newValue);
            }
        });

        margin.textProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue != null) {
                log.info("margin exchange : {}", newValue);
            }
        });
    }

    public static void generate(String content, int width, int height, File targetFile) {
        QrCodeUtil.generate(content, width, height, targetFile);
    }

    public static void generate(String content, int width, int height, int margin, Color fore_color, Color back_color, File targetFile) {
        QrConfig config = new QrConfig(width, height);
        // 设置边距，既二维码和背景之间的边距
        config.setMargin(margin);
        // 设置前景色，既二维码颜色（青色）
        config.setForeColor(fore_color);
        // 设置背景色（灰色）
        config.setBackColor(back_color);
        QrCodeUtil.generate(content, config, targetFile);
    }

    public static void generate(String content, int width, int height, int margin, Color fore_color, Color back_color, File logo, File targetFile) {
        QrConfig config = new QrConfig(width, height);
        // 设置边距，既二维码和背景之间的边距
        config.setMargin(margin);
        // 设置前景色，既二维码颜色（青色）
        config.setForeColor(fore_color);
        // 设置背景色（灰色）
        config.setBackColor(back_color);
        config.setImg(logo);
        QrCodeUtil.generate(content, config, targetFile);
    }

    public static void generate(String content, int width, int height, int margin, Color fore_color, Color back_color, File logo, ErrorCorrectionLevel errorCorrectionLevel, File targetFile) {
        QrConfig config = new QrConfig(width, height);
        // 设置边距，既二维码和背景之间的边距
        config.setMargin(margin);
        // 设置前景色，既二维码颜色（青色）
        config.setForeColor(fore_color);
        // 设置背景色（灰色）
        config.setBackColor(back_color);
        config.setImg(logo);
        config.setErrorCorrection(errorCorrectionLevel);
        QrCodeUtil.generate(content, config, targetFile);
    }

    public static String decode(File file) {
        return QrCodeUtil.decode(file);
    }


}
